package com.woniu.after.service.impl;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;

import java.util.ArrayList;
import java.util.List;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu.after.common.OrderException;
import com.woniu.after.common.RefundResonException;
import com.woniu.after.common.RefundsApplyException;
import com.woniu.after.infra.model.Refundreson;
import com.woniu.after.infra.model.Refunds;
import com.woniu.after.infra.model.RefundsApply;
import com.woniu.after.infra.mapper.RefundsApplyMapper;
import com.woniu.after.service.RefundresonService;
import com.woniu.after.service.RefundsApplyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.after.service.RefundsService;
import com.woniu.after.service.dto.PageRefundsApplyDto;
import com.woniu.after.service.dto.RefundsApplyDto;
import com.woniu.after.service.dto.RefundsDto;
import com.woniu.after.service.form.PageRefundsApplyForm;
import com.woniu.after.service.form.RefundsApplyForm;
import com.woniu.after.service.form.RefundsMoneyForm;
import com.woniu.exception.LXLGException;
import com.woniu.order.client.OrderEntryQueryClient;
import com.woniu.order.client.OrderManageClient;
import com.woniu.order.client.OrderQueryClient;
import com.woniu.order.client.param.AddOrderFlowingParam;
import com.woniu.order.client.param.OrderEntryParam;
import com.woniu.order.client.param.SearchOrderEntryParam;
import com.woniu.order.client.result.OrderEntryQueryResultInfo;
import com.woniu.order.client.result.OrderFlowingResultInfo;
import com.woniu.order.client.result.OrderQueryResultInfo;
import com.woniu.result.Result;
import com.woniu.util.DateUtil;
import org.springframework.stereotype.Service;
import com.google.common.base.Joiner;

import javax.annotation.Resource;

/**
 * <p>
 * 退款申请表 服务实现类
 * </p>
 *
 * @author jianlang
 * @since 2022-11-26
 */
@Service
public class RefundsApplyServiceImpl extends ServiceImpl<RefundsApplyMapper, RefundsApply> implements RefundsApplyService {
    @Resource
    private OrderQueryClient orderQueryClient;

    @Resource
    private RefundresonService refundresonService;

    @Resource
    private OrderEntryQueryClient orderEntryQueryClient;

    @Resource
    private OrderManageClient orderManageClient;

    @Resource
    private RefundsService refundsService;

    @Override
    public RefundsApplyDto refundsApply(RefundsApplyForm refundsApplyForm) {
        Result<OrderQueryResultInfo> orderQueryResultInfoResult = orderQueryClient.searchOrderByOrderId(refundsApplyForm.getOrderId());
        if (!orderQueryResultInfoResult.isSuccess() || orderQueryResultInfoResult.getData() == null)
            throw new LXLGException(OrderException.ORDER_NON_EXISTENT);
        Refundreson byId = refundresonService.getById(refundsApplyForm.getRefundresonId());
        if (byId == null) throw new LXLGException(RefundResonException.REFUNDRESON_NON_EXISTENT);
        RefundsApply refundsApply = BeanUtil.copyProperties(refundsApplyForm, RefundsApply.class);
        refundsApply.setOrderNum(orderQueryResultInfoResult.getData().getOrderNum());
        if (refundsApplyForm.getProductId() != null && refundsApplyForm.getProductId().size() > 0) {
            List<Integer> productIds = refundsApplyForm.getProductId();
            //对ids排序
            Collections.sort(productIds);
            //用,连接
            String ids = Joiner.on(',').join(productIds);

            refundsApply.setProductId(ids);

            BigDecimal allPrice = new BigDecimal(0);
            for (Integer productId : productIds) {
                SearchOrderEntryParam searchOrderEntryParam = new SearchOrderEntryParam();
                searchOrderEntryParam.setOrderId(orderQueryResultInfoResult.getData().getOrderId());
                searchOrderEntryParam.setSkuId(productId);

                OrderEntryQueryResultInfo data = orderEntryQueryClient.searchOrderEntry(searchOrderEntryParam).getData();
                System.out.println(data);
                BigDecimal multiply = data.getPrice().multiply(BigDecimal.valueOf(data.getQuantity()));
                allPrice = allPrice.add(multiply);
            }
            refundsApply.setBackMoney(allPrice);
        } else {
            refundsApply.setProductId("");
            refundsApply.setBackMoney(orderQueryResultInfoResult.getData().getOrderPrice());
        }
        refundsApply.setState("1");
        refundsApply.setApplyTime(DateUtil.parseDateLong());
        save(refundsApply);
        return BeanUtil.copyProperties(refundsApply, RefundsApplyDto.class);
    }

    @Override
    public PageRefundsApplyDto listRefundsApply(PageRefundsApplyForm pageRefundsApplyForm) {
        QueryWrapper<RefundsApply> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("apply_time");
        if (pageRefundsApplyForm.getKeyword() != null && !pageRefundsApplyForm.getKeyword().trim().equals("")) {
            wrapper.and(q -> q.like("user_id", pageRefundsApplyForm.getKeyword()).or()
                    .like("user_num", pageRefundsApplyForm.getKeyword()).or()
                    .like("order_id", pageRefundsApplyForm.getKeyword()).or()
                    .like("order_num", pageRefundsApplyForm.getKeyword()).or()
                    .like("refundOtherReson", pageRefundsApplyForm.getKeyword()));
        }
        if (pageRefundsApplyForm.getState() != null && !pageRefundsApplyForm.getState().trim().equals("")) {
            wrapper.eq("state", pageRefundsApplyForm.getState());
        }
        IPage<RefundsApply> page = page(new Page<RefundsApply>(pageRefundsApplyForm.getIndexPage(), pageRefundsApplyForm.getPageSize()), wrapper);
        PageRefundsApplyDto pageRefundsApplyDto = new PageRefundsApplyDto();
        pageRefundsApplyDto.setTotal(page.getTotal());
        pageRefundsApplyDto.setIndexPage(page.getCurrent());
        pageRefundsApplyDto.setRefundsApplyDtoList(BeanUtil.copyToList(page.getRecords(), RefundsApplyDto.class));
        return pageRefundsApplyDto;
    }

    @Override
    public RefundsDto refundsMoney(RefundsMoneyForm refundsMoneyForm) {
        RefundsApply refundsApply = getById(refundsMoneyForm.getRefundsApplyId());
        if (refundsApply == null) throw new LXLGException(RefundsApplyException.REFUNDS_APPLY_NON_EXISTENT);
        if (refundsApply.getState().equals("0")) throw new LXLGException(RefundsApplyException.REFUNDS_APPLY_PROCESSED);
        //修改申请状态
        refundsApply.setState("0");
        updateById(refundsApply);

        //查询订单数据
        Result<OrderQueryResultInfo> orderQueryResultInfoResult = orderQueryClient.searchOrderByOrderId(refundsApply.getOrderId());
        if (!orderQueryResultInfoResult.isSuccess() || orderQueryResultInfoResult.getData() == null)
            throw new LXLGException(OrderException.ORDER_NON_EXISTENT);
        OrderQueryResultInfo order = orderQueryResultInfoResult.getData();

        //生成退款表数据
        Refunds refunds = new Refunds();
        refunds.setOrderId(order.getOrderId());
        refunds.setOrderNum(order.getOrderNum());
        refunds.setRefundResongId(refundsApply.getRefundresonId());
        refunds.setRefundOtherReson(refundsApply.getRefundOtherReson());

        OrderFlowingResultInfo orderFlowingResultInfo = null;
        if (refundsApply.getProductId() == null || refundsApply.getProductId().equals("")) {//全部退货
            refunds.setBackMoney(order.getOrderPrice());
            //退款流水记录
            AddOrderFlowingParam addOrderFlowingParam = new AddOrderFlowingParam();
            addOrderFlowingParam.setOrderId(order.getOrderId());
            addOrderFlowingParam.setFlowingType("退款");
            addOrderFlowingParam.setOrderPrice(order.getOrderPrice());
            addOrderFlowingParam.setCreateTime(new Date());

            orderFlowingResultInfo = orderManageClient.addOrderFlowing(addOrderFlowingParam).getData();
        } else {//部分退货
            //productId拆分
            String[] split = refundsApply.getProductId().split(",");
            BigDecimal allPrice = new BigDecimal(0);
            for (String s : split) {
                Integer productId = Integer.parseInt(s);
                SearchOrderEntryParam searchOrderEntryParam = new SearchOrderEntryParam();
                searchOrderEntryParam.setOrderId(refundsApply.getOrderId());
                searchOrderEntryParam.setSkuId(productId);

                OrderEntryQueryResultInfo data = orderEntryQueryClient.searchOrderEntry(searchOrderEntryParam).getData();

                BigDecimal multiply = data.getPrice().multiply(BigDecimal.valueOf(data.getQuantity()));
                allPrice = allPrice.add(multiply);
            }
            refunds.setBackMoney(allPrice);
            System.out.println("部分还款总价格:" + allPrice);

            AddOrderFlowingParam addOrderFlowingParam = new AddOrderFlowingParam();
            addOrderFlowingParam.setOrderId(order.getOrderId());
            addOrderFlowingParam.setFlowingType("退款");
            addOrderFlowingParam.setOrderPrice(allPrice);
            addOrderFlowingParam.setCreateTime(new Date());

            orderFlowingResultInfo = orderManageClient.addOrderFlowing(addOrderFlowingParam).getData();
        }
        refunds.setRefundTradeNo(orderFlowingResultInfo.getFlowingId() + "");
        refunds.setRefundRemark(refundsMoneyForm.getRefundRemark());
        refunds.setRefundTime(DateUtil.parseDateLong());
        refunds.setShopRejectReason("");
        refunds.setRefundStatus(1);
        refunds.setCreateTime(DateUtil.parseDateLong());
        refunds.setBackScore(0);
        refunds.setRefundsApplyId(refundsApply.getId());
        System.out.println(refunds);
        refundsService.save(refunds);
        return BeanUtil.copyProperties(refunds, RefundsDto.class);
    }

}
